package com.tony.juc;

import java.util.Objects;
import java.util.concurrent.atomic.AtomicMarkableReference;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * Created with IntelliJ IDEA.
 *
 * @Title: AtomicReference
 * @Auther: 皮蛋布丁
 * @Date: 2022/04/05/21:52
 * @Description: 引用类型原子操作类
 */
public class AtomicReferenceDemo001 {

    public static void main(String[] args) {

        /*Book001 book = new Book001("java就业编程实战",69.8); //定义图书对象
        AtomicReference ref = new AtomicReference(book); // 原子引用
        ref.compareAndSet(book,new Book001("spring就业编程实战",67.8));//数据更改
        System.out.println(ref);*/

        //此时的程序代码变为了一个匿名对象，直接存储的是一个匿名对象，没有栈内存的指向
        //即使实体类重写了equal()、hashCode()方法，结果依旧我无法替换
        /*AtomicReference ref = new AtomicReference(new Book001("java就业编程实战",69.8));
        ref.compareAndSet(new Book001("java就业编程实战",69.8),new Book001("spring就业编程实战",67.8)); //数据更改
        System.out.println(ref);*/

        //适合多种情况的
        /*Book001 book1 = new Book001("java就业编程实战",69.8);
        Book001 book2 = new Book001("spring就业编程实战",67.8);
        //1是一个版本编号，按照正常的设计来讲，每一次修改之后版本编号不匹配，无法进行内容的修改
        AtomicStampedReference<Book001> ref = new AtomicStampedReference<>(book1,1);
        //现在保存的版本号是1，但是此时匹配的版本号是3，那么版本号不匹配，无法进行内容的修改
        System.err.println("【×引用内容修改】" + ref.compareAndSet(book1, book2, 3, 5));
        System.err.println("【×原子引用数据】版本戳：" + ref.getStamp() + "、存储内容：" + ref.getReference());
        System.out.println("【√引用内容修改】" + ref.compareAndSet(book1, book2, 1, 2));
        System.out.println("【√原子引用数据】版本戳：" + ref.getStamp() + "、存储内容：" + ref.getReference());*/

        //适合只有两种情况的
        /*Book001 book1 = new Book001("Java就业编程实战", 69.8);
        Book001 book2 = new Book001("Spring就业编程实战", 67.8);
        AtomicMarkableReference<Book001> ref = new AtomicMarkableReference<>(book1, true);
        // 在数据修改之前首先要进行当前标记状态的判断，此时的状态标记不符合要求，所以一定无法修改成功
        System.err.println("【×引用内容修改】" + ref.compareAndSet(book1, book2, false, true));
        System.err.println("【×原子引用数据】标记：" + ref.isMarked() + "、存储内容：" + ref.getReference());
        System.out.println("【√引用内容修改】" + ref.compareAndSet(book1, book2, true, false));
        System.out.println("【√原子引用数据】标记：" + ref.isMarked() + "、存储内容：" + ref.getReference());*/


    }
}
class Book001 {
    private String title; //名称
    private double price; //价格
    public Book001(String title,double price) {
        this.title = title;
        this.price = price;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Book001 book001 = (Book001) o;
        return Double.compare(book001.price, price) == 0 &&
                Objects.equals(title, book001.title);
    }

    @Override
    public int hashCode() {
        return Objects.hash(title, price);
    }

    @Override
    public String toString() {
        return "【图书】名称 = " + this.title + "、价格 = " + this.price;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}
